[IA64] Implement XENMEM_machine_memory_map on ia64.
authorAlex Williamson <alex.williamson@hp.com>
Thu, 10 May 2007 21:55:22 +0000 (15:55 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 10 May 2007 21:55:22 +0000 (15:55 -0600)
This is necessary for kexec/kdump for xen/ia64. kexec-tools needs to know
real machine's memory map.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c
linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c
xen/arch/ia64/xen/mm.c
xen/include/public/arch-ia64.h

index b14db04ee68b89e2e65b944f719e2b86af3a7324..4c90b5b01e5f70fdac6d3f72a6ee6c32d698f4fa 100644 (file)
@@ -226,6 +226,8 @@ xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
 {
        XEN_GUEST_HANDLE(xen_pfn_t) extent_start_va[2];
        xen_memory_reservation_t *xmr = NULL, *xme_in = NULL, *xme_out = NULL;
+       xen_memory_map_t *memmap = NULL;
+       XEN_GUEST_HANDLE(void) buffer;
        int rc;
 
        switch (cmd) {
@@ -254,6 +256,14 @@ xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
                        (&((xen_memory_exchange_t *)arg)->out);
                break;
 
+       case XENMEM_machine_memory_map:
+               memmap = (xen_memory_map_t *)arg;
+               xen_guest_handle(buffer) = xen_guest_handle(memmap->buffer);
+               set_xen_guest_handle(memmap->buffer,
+                       (void *)xencomm_create_inline(
+                               xen_guest_handle(memmap->buffer)));
+               break;
+
        default:
                printk("%s: unknown memory op %d\n", __func__, cmd);
                return -ENOSYS;
@@ -275,6 +285,10 @@ xencomm_hypercall_memory_op(unsigned int cmd, void *arg)
                xen_guest_handle(xme_out->extent_start) =
                        xen_guest_handle(extent_start_va[1]);
                break;
+
+       case XENMEM_machine_memory_map:
+               xen_guest_handle(memmap->buffer) = xen_guest_handle(buffer);
+               break;
        }
 
        return rc;
index dd45ce943cde7340611f523d4b8e6f64a82c42ab..3c0baff1f0479986e366d46aa6bde01c13137b0e 100644 (file)
@@ -238,6 +238,19 @@ xencomm_mini_hypercall_memory_op(unsigned int cmd, void *arg)
                argsize = sizeof (xen_add_to_physmap_t);
                break;
 
+       case XENMEM_machine_memory_map:
+       {
+               xen_memory_map_t *memmap = (xen_memory_map_t *)arg;
+               argsize = sizeof(*memmap);
+               rc = xencomm_create_mini(xc_area, &nbr_area,
+                                        xen_guest_handle(memmap->buffer),
+                                        memmap->nr_entries, &desc);
+               if (rc)
+                       return rc;
+               set_xen_guest_handle(memmap->buffer, (void *)desc);
+               break;
+       }
+
        default:
                printk("%s: unknown mini memory op %d\n", __func__, cmd);
                return -ENOSYS;
index 367ed5a0dd908ba718af6488ab576bd02dc669f3..753636e147e7b1843ea9489f6b3f2399a7322c8f 100644 (file)
@@ -2145,6 +2145,37 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg)
         break;
     }
 
+    case XENMEM_machine_memory_map:
+    {
+        struct xen_memory_map memmap;
+        struct xen_ia64_memmap_info memmap_info;
+        XEN_GUEST_HANDLE(char) buffer;
+
+        if (!IS_PRIV(current->domain))
+            return -EINVAL;
+        if (copy_from_guest(&memmap, arg, 1))
+            return -EFAULT;
+        if (memmap.nr_entries <
+            sizeof(memmap_info) + ia64_boot_param->efi_memmap_size)
+            return -EINVAL;
+
+        memmap.nr_entries =
+            sizeof(memmap_info) + ia64_boot_param->efi_memmap_size;
+        memset(&memmap_info, 0, sizeof(memmap_info));
+        memmap_info.efi_memmap_size = ia64_boot_param->efi_memmap_size;
+        memmap_info.efi_memdesc_size = ia64_boot_param->efi_memdesc_size;
+        memmap_info.efi_memdesc_version = ia64_boot_param->efi_memdesc_version;
+
+        buffer = guest_handle_cast(memmap.buffer, char);
+        if (copy_to_guest(buffer, (char*)&memmap_info, sizeof(memmap_info)) ||
+            copy_to_guest_offset(buffer, sizeof(memmap_info),
+                                 (char*)__va(ia64_boot_param->efi_memmap),
+                                 ia64_boot_param->efi_memmap_size) ||
+            copy_to_guest(arg, &memmap, 1))
+            return -EFAULT;
+        return 0;
+    }
+
     default:
         return -ENOSYS;
     }
index 9b27394da787ddf8c99c11a375510340a024c984..ac0bae0a7b3ce5c91887e030a5e4ff709d043f03 100644 (file)
@@ -317,6 +317,21 @@ struct arch_vcpu_info {
 };
 typedef struct arch_vcpu_info arch_vcpu_info_t;
 
+/*
+ * This structure is used for magic page in domain pseudo physical address
+ * space and the result of XENMEM_machine_memory_map.
+ * As the XENMEM_machine_memory_map result,
+ * xen_memory_map::nr_entries indicates the size in bytes 
+ * including struct xen_ia64_memmap_info. Not the number of entries.
+ */
+struct xen_ia64_memmap_info {
+    uint64_t efi_memmap_size;       /* size of EFI memory map */
+    uint64_t efi_memdesc_size;      /* size of an EFI memory map descriptor */
+    uint32_t efi_memdesc_version;   /* memory descriptor version */
+    void *memdesc[0];               /* array of efi_memory_desc_t */
+};
+typedef struct xen_ia64_memmap_info xen_ia64_memmap_info_t;
+
 struct arch_shared_info {
     /* PFN of the start_info page.  */
     unsigned long start_info_pfn;